package sw6.visualschedule.adminpanel;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import sw6.visualschedule.R;
import sw6.visualschedule.entities.ScheduleActivity;
import sw6.visualschedule.entities.Step;
import sw6.visualschedule.extendedViews.CustomEntry;
import sw6.visualschedule.extendedViews.SeperatorEntry;
import sw6.visualschedule.persistence.ScheduleActivityRepo;
import sw6.visualschedule.persistence.StepRepo;
import tools.BundleHelper;
import tools.DialogHelper;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.Toast;

import com.commonsware.cwac.sacklist.SackOfViewsAdapter;

/**
 * Activity, which is responsible for creating and editing steps.
 */
public class StepConstructor extends ListActivity {
	
	//Entry constants
	//Required Bar
	final private static int TITLE_ENTRY = 1;
	final private static int IMAGE_ENTRY = 2;
	//Optional bar
	final private static int AUDIO_ENTRY = 4;
	
	//Databases
	private ScheduleActivityRepo mActivityDb;
	private StepRepo mStepDb;
	
	//Objects
	private ScheduleActivity mActivity;
	private Step mStep;
	
	//ID's
	private int mStepId;
	
	//Entries
	private CustomEntry mTitleEntry;
	
	private CustomEntry mImageEntry;
	private CustomEntry mAudioEntry;
	
	//Diverse
	private String mCameraImagePath = "";
	
	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
		//Initiate databases
		mStepDb = new StepRepo(this);
		
		//Get objects
		final int activityId = getIntent().getIntExtra(BundleHelper.ACTIVITY_ID, -1);
		mStepId = getIntent().getIntExtra(BundleHelper.STEP_ID, -1);
		
		if (activityId != -1 && savedInstanceState == null) {
			mActivityDb = new ScheduleActivityRepo(this);
			mActivity = mActivityDb.getById(activityId);
		}
		
		if (mStepId == -1 && savedInstanceState == null) {
			setTitle(getString(R.string.step_construct));
			mStep = new Step(mActivity, getString(R.string.adm_sc_step_default_name));
			mStepDb.create(mStep);
			mStepId = mStep.getId();
		} else if(savedInstanceState != null) {
			mStepId = savedInstanceState.getInt(BundleHelper.STEP_ID);
			mCameraImagePath = savedInstanceState.getString(BundleHelper.CAMERA_PATH);
		}
		mStep = mStepDb.getById(mStepId);
	}
	
	
	@Override
	public void onResume() {
		super.onResume();
		
		if (mStep == null) {
			mStep = mStepDb.getById(mStepId);
		}
		
		/*
		 * Initiate setting entries
		 */
		
		final List<View> views = populate();
		
		setListAdapter(new SackOfViewsAdapter(views));
	}
	
	public void onSaveInstanceState(final Bundle savedInstanceState) {
		// Save UI state changes to the savedInstanceState.
		// This bundle will be passed to onCreate if the process is
		// killed and restarted.
		savedInstanceState.putInt(BundleHelper.STEP_ID, mStep.getId());
		//When opening the camera intent this activity will be killed, and therefore we need to store the camera image path.
		savedInstanceState.putString(BundleHelper.CAMERA_PATH, mCameraImagePath);
		
		super.onSaveInstanceState(savedInstanceState);
	}
	
	protected final void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        
        if (resultCode != RESULT_OK) {
		    return;
		}
    
        switch (requestCode) {
            case BundleHelper.IMAGE_SD_RESULT:
                mStep.setImage(getPath(intent.getData()));
                mStepDb.update(mStep);
                break;
            case BundleHelper.IMAGE_CAM_RESULT:
                //The intent recieved from the camera intent does not contain the path to the image just created, there for this is store as a property on the step.
                mStep.setImage(mCameraImagePath);
                mStepDb.update(mStep);
                break;
            case BundleHelper.AUDIO_RESULT:
                mStep.setAudio(getPath(intent.getData()));
                mStepDb.update(mStep);
                break;
            default:
                break;
        }
	}
	   
    @Override
    protected void onListItemClick(final ListView list, final View view, final int position, final long itemId) {
        
        Intent intent;
        final int viewId = view.getId();
        
        switch (viewId) {
        case TITLE_ENTRY:
        		DialogHelper.showTitleEntryDialog(mStepDb, mStep, this, ((CustomEntry)view));
            break;
            
        case IMAGE_ENTRY:
            showImageEntryDialog();
            break;
            
        case AUDIO_ENTRY:
            intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, BundleHelper.AUDIO_RESULT);
            break;
        
        default:
            break;
        }
    }
	
	private List<View> populate() {
		final List<View> views = new ArrayList<View>();
		
		views.add(new SeperatorEntry(this, getString(R.string.constructor_required)));
		
		//Title
		mTitleEntry = new CustomEntry(this);
		mTitleEntry.setId(TITLE_ENTRY);
		mTitleEntry.getTitle().setText(getString(R.string.adm_sc_step_title));
		mTitleEntry.getSummary().setText(mStep.getTitle());
		views.add(mTitleEntry);

		//Image
		mImageEntry = new CustomEntry(this);
		mImageEntry.setId(IMAGE_ENTRY);
		mImageEntry.getTitle().setText(getString(R.string.adm_sc_select_image));
		mImageEntry.getSummary().setText(mStep.getImage());
		views.add(mImageEntry);

		
		views.add(new SeperatorEntry(this, getString(R.string.adm_sc_optional)));
		
		//Audio
		mAudioEntry = new CustomEntry(this);
		mAudioEntry.setId(AUDIO_ENTRY);
		mAudioEntry.getTitle().setText(getString(R.string.adm_sc_select_audio));
		mAudioEntry.getSummary().setText(mStep.getAudio());
		views.add(mAudioEntry);
		
		return views;
	}

	private void showImageEntryDialog() {
	    final AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle(getString(R.string.adm_ac_select_source));
        alert.setItems(new CharSequence[] {getString(R.string.adm_ac_from_storage), getString(R.string.adm_ac_from_cam)}, new DialogInterface.OnClickListener() {
            public void onClick(final DialogInterface dialog, final int item) {
                Intent internalIntent;
                switch (item) {
                case 0:// From SD card
                    internalIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(internalIntent, BundleHelper.IMAGE_SD_RESULT);
                    break;
                case 1:// From camera
                    internalIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    //TODO: make better unique name for image.
                    final Date date = new Date();
                    final File photo = new File(Environment.getExternalStorageDirectory()+"/DCIM/Camera/",  "STEP"+mStepId+"("+(date.getMonth()+1)+"-"+date.getDate()+"-"+date.getYear()+"."+date.getHours()+"."+date.getMinutes()+"."+date.getSeconds()+").jpg");
                    final Uri uri = Uri.fromFile(photo);
                    mCameraImagePath = uri.getPath();
                    
                    internalIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    startActivityForResult(internalIntent, BundleHelper.IMAGE_CAM_RESULT);
                    break;
                default:
                    break;
                }
            }
        });
        alert.show();
	}
	
	/**
	 * Calls the super class' onBackPressed() method.
	 */
	public void superOnBackPressed() {
		super.onBackPressed();
	}
	
	@Override
	public void onBackPressed() {
		final String result = validateStep();
		if (result.equalsIgnoreCase("")) {
			super.onBackPressed();
			Toast.makeText(this, R.string.adm_sc_step_saved, Toast.LENGTH_SHORT).show();
		} else {
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(R.string.constructor_confirmation);
			builder.setMessage(getString(R.string.adm_sc_error_save)+"\n"+result);
			builder.setPositiveButton(getString(R.string.adm_sc_delete_quit), new OnClickListener() {
				
				@Override
				public void onClick(final DialogInterface dialog, final int which) {
					StepConstructor.this.superOnBackPressed();
		        	Toast.makeText(getApplicationContext(), R.string.adm_sc_step_deleted, Toast.LENGTH_SHORT).show();
		        	mStepDb.delete(mStep);
				}
			});
			builder.setNegativeButton(getString(R.string.adm_sc_edit_stay), null);
			builder.show();
		}
	}
	
	private String validateStep() {
		String result = "";
	    
		if (mStep.getTitle().length() <= 0) {
			result = getString(R.string.adm_sc_step_require_title);
		} else if (mStep.getImage() == null) {
			result = getString(R.string.adm_sc_step_missing_image);
		}
		return result;
	}


	private String getPath(final Uri uri) {
        final String[] projection = {
            MediaColumns.DATA
        };
        final Cursor cursor = managedQuery(uri, projection, null, null, null);

        final int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
        cursor.moveToFirst();

        return cursor.getString(column_index);
    }
}
